//引入node模块，一会操作文件，输入，生成，输出都是需要这个路径
const path = require('path');

const { defineConfig } = require('@vue/cli-service');
const { compileTemplate } = require('@vue/compiler-dom');
//css剥离到独立文件
//引入gzip压缩插件
const CompressionPlugin = require('compression-webpack-plugin');
const packageName = require('./package.json').name;
//自动导入全局插件
const unpluginAutoImport = require('unplugin-auto-import/webpack');
const Components = require('unplugin-vue-components/webpack');
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');
const { ModuleFederationPlugin } = require('@module-federation/enhanced/webpack');
const glob = require('glob');

//开发环境动态设置反向代理url，不需要重新启动
const getActiveProxy = require('./proxy-url');

// 查找 src/modules/*/config.js 下所有的 config.js 文件
const configFiles = glob.sync('./src/modules/*/config.js');

const moduleFederationPlugins = [];

configFiles.forEach((configFile) => {
  let { moduleFederation: mf } = require(path.resolve(__dirname, configFile));

  if (!Array.isArray(mf)) {
    mf = [mf];
  }
  for (const config of mf) {
    if (config.name) {
      moduleFederationPlugins.push(new ModuleFederationPlugin(config));
    }
  }
});

module.exports = defineConfig({
  // 资源是否需要进行转义
  transpileDependencies: [],

  // 配置部署应用包时的基本 URL
  publicPath: process.env.NODE_ENV === 'development' ? 'http://localhost:8087/' : process.env.VUE_APP_PUBLIC_PATH,
  // publicPath: process.env.NODE_ENV === 'development' ? '/custom-dev/' : process.env.VUE_APP_PUBLIC_PATH,

  // 配置输出文件的目录
  outputDir: process.env.outputDir,

  // 配置静态资源的目录
  assetsDir: 'static',

  // 是否使用 eslint-loader 在开发过程中校验代码
  lintOnSave: process.env.NODE_ENV !== 'production',

  // 配置 Webpack 的相关选项
  configureWebpack: {
    externals: {
      vue: 'Vue'
    },
    plugins: [
      //组件按需自动注册
      Components({
        resolvers: [ElementPlusResolver()]
      }),

      unpluginAutoImport.default({
        imports: ['vue', 'vue-router'],
        eslintrc: {
          enabled: true,
          filepath: './.eslintrc-auto-import.json'
        }
      }),

      ...moduleFederationPlugins
    ]
  },
  chainWebpack: (config) => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap((options) => {
        options.hotReload = false;
        options.compiler = compileTemplate; // 将 compileTemplate 函数赋值给编译器选项
        return options;
      });
    config.module.rule('svg').exclude.add(resolve('src/form-designer/icons')).end();
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/form-designer/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end();
    // 配置url-loader处理字体文件
    config.module
      .rule('fonts')
      .test(/\.(ttf|otf|eot|woff|woff2)$/)
      .use('url-loader')
      .loader('url-loader')
      .tap((options) => {
        return options;
      });
    // 不拷贝public下的资源
    config.plugins.delete('copy');

    /* 为nanoid设置别名  
      在Vue 3中，nanoid默认使用了非安全的随机算法，而webpack默认会使用安全的随机算法。
      通过将别名设置为nanoid/non-secure，我们可以告诉webpack使用非安全的随机算法来解决这个问题
    */
    config.resolve.alias.set('nanoid', 'nanoid/non-secure');
  },
  // 配置开发服务器的行为
  devServer: {
    //open: true,
    host: '0.0.0.0',
    hot: true,
    port: 8087,
    https: false,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Headers': '*',
      'Access-Control-Allow-Methods': '*'
    },
    proxy: {
      '/rest': {
        target: 'http://127.0.0.1:8083/rest', //API服务器的地址。该行请勿修改或者删除，要配其他ip请注释该行，选用下面的ip地址/
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/rest': ''
        },
        router: () => {
          return getActiveProxy('rest');
        },
        onProxyRes: function (proxyRes, req) {
          if (req.method === 'OPTIONS') {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Allow-Methods'] = 'GET,POST,OPTIONS,PUT,DELETE,FETCH';
            // 这里的参数，根据自己项目增删
            proxyRes.headers['Access-Control-Allow-Headers'] =
              'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,userid,w3auth,requestbybrowser,tyinjectparams';
            proxyRes.statusCode = 204;
          } else {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Expose-Headers'] = '*';
          }
        }
      },
      '/typrjmng': {
        target: 'http://192.168.220.26:9588', //API服务器的地址。该行请勿修改或者删除，要配其他ip请注释该行，选用下面的ip地址
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          '^/api': '/api'
        },
        router: () => {
          return getActiveProxy('api');
        },
        onProxyRes: function (proxyRes, req) {
          if (req.method === 'OPTIONS') {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Allow-Methods'] = 'GET,POST,OPTIONS,PUT,DELETE,FETCH';
            proxyRes.headers['Access-Control-Allow-Headers'] =
              'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,userid,w3auth,requestbybrowser,tyinjectparams';
            proxyRes.statusCode = 204;
          } else {
            proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || req.headers.referer || '*';
            proxyRes.headers['Access-Control-Allow-Credentials'] = true;
            proxyRes.headers['Access-Control-Expose-Headers'] = '*';
          }
        }
      },
      '/mock': {
        target: 'http://127.0.0.1:8887/mock',
        changeOrigin: true,
        pathRewrite: {
          '^/mock': ''
        },
        router: () => {
          return getActiveProxy('mock');
        }
      }
    }
  }
});

function resolve(dir) {
  return path.join(__dirname, dir);
}
